Operating systems typically include large numbers of callable functions that are structured to support operation on a single host machine. When an application executes on the single host machine, it interacts with the operating system by making one or more calls to the operating system's functions.
Although this method of communicating with an operating system has been adequate, it has certain shortcomings. One such shortcoming relates to the increasing use of distributed computing, in which different computers are programmed to work in concert on a particular task. Specifically, operating system function libraries can severely limit the ability to perform distributed computing.
FIG. 1 illustrates the use of functions in prior art operating systems. FIG. 1 shows a system 20 that includes an operating system 22 and an application 24 executing in conjunction with the operating system 22. In operation, the application 24 makes calls directly into the operating system when, for example, it wants to create or use an operating system resource. As an example, if an application wants to create a file, it might call a “CreateFile” function at 26 to create the file. Responsive to this call, the operating system returns a “handle” 28. A “handle” is an arbitrary identifier, coined by the operating system to identify a resource that is controlled by the operating system. In this example, the application uses handle 28 to identify the newly created file resource any time it makes subsequent calls to the operating system to manipulate the file resource. For example, if the application wants to read the file associated with handle 28, it uses the handle when it makes a “ReadFile” call, e.g. “ReadFile (handle)”. Similarly, if the application wants to write to the file resource it uses handle 28 when it makes a “WriteFile” call, e.g. “WriteFile (handle)”.
One problem associated with using a handle as specified above is that the particular handle that is returned to an application by the operating system is only valid for the process in which it is being used. That is, without special processing the handle has no meaning outside of its current process, e.g. in another process on a common or different machine. Hence, the handle cannot be used across process or machine boundaries. This makes computing in a distributed computing system impossible because, by definition, distributed computing takes place across process and machine boundaries. Thus, current operating systems lack the ability to name and manipulate operating system resources on remote machines.
Another problem with traditional operating system function libraries is that individual functions cannot generally be modified without jeopardizing the operation of older versions of applications that might depend on the particular characteristics of the individual functions. Thus, when an operating system is upgraded it typically maintains all of the older functions so that older applications can still use the operating system.
In prior art operating systems, a function library essentially defines a protocol for communicating with an operating system. When operating systems are upgraded, the list of functions that it provides typically changes. Specifically, functions can be added, removed, or changed. This changes the protocol that is used between an application and an operating system. As soon as the protocol is changed, the chances that an application will attempt to use a protocol that is not understood by the operating system, and vice versa increase.
Prior art operating systems attempt to deal with new versions of operating systems by using so-called version numbers. Version numbers are assigned to each operating system. Applications can make specific calls to the operating system to ascertain the version number of the operating system that is presently in use. For example, when queried by an application, Windows NT 4 returns a “4” and Windows NT 5 returns a “5”. The application must then know what specific protocol to use when communicating with the operating system. In addition, in order for an operating system to know what operating system version the application was designed for, a value is included in the application's binary. The operating system can then attempt to accommodate the application's protocol.
The version number system has a couple of problems that can adversely affect functionality. Specifically, a typical operating system may have thousands of functions that can be called by an application. For example, Win32, a Microsoft operating system application programming interface, has some 8000 functions. The version number that is assigned to an operating system then, by definition, represents all of the possibly thousands of functions that an operating system supports. This level of description is undesirable because it does not provide an adequate degree of resolution. Additionally, some operating systems can return the same version number. Thus, if the operating systems are different (which they usually are), then returning the same version number can lead to operating errors. What is needed is the ability to identify different versions of operating systems at a level that is lower than the operating system level itself. Ideally, this level should be at or near the function level so that a change in just one or a few functions does not trigger a new version number for the entire operating system.
The present invention arose out of concerns associated with providing improved flexibility to operating systems. Specifically, the invention arose out of concerns associated with providing operating systems that are configured for use in distributed computing environments, and that can easily support legacy applications and versioning.